﻿/**
 *
 * sspi.c
 *
 *  Created on: 2018-09-05
 *      Author: chenshisheng
 */

#include "sspi.h"

#define DO_DELAY 1

#if DO_DELAY
#   define _DELAY() _Delay()
#else
#   define _DELAY()
#endif


void SSPI_Init(void)
{

}

#if DO_DELAY
static void _Delay(void)
{
    uint8_t i;

    for(i = 0; i < 2; i++)
    {
        nop();
    }
}
#endif

void SSPI_SelectCmd(const HW_t *stb, bool select)
{
    if(select)
    {
        HW_CLR(stb);
    }
    else
    {
        HW_SET(stb);
    }

    _DELAY();
}

void SSPI_SendByte(const HW_t *clk, const HW_t *dio, uint8_t b)
{
    uint8_t i;

    for(i = 0; i < 8; i++)
    {
        HW_CLR(clk);
        if(b & 0x01)
        {
            HW_SET(dio);
        }
        else
        {
            HW_CLR(dio);
        }

        _DELAY();
        HW_SET(clk);
        _DELAY();

        b >>= 1;
    }
}

void SSPI_Send(const HW_t *clk, const HW_t *dio, const void *data, unsigned int size)
{
    const uint8_t *vdata;

    vdata = (const uint8_t *) data;
    while(size--)
    {
        SSPI_SendByte(clk, dio, *vdata++);
    }
}

uint8_t SSPI_RecvByte(const HW_t *clk, const HW_t *dio)
{
    uint8_t b, i, x;

    b = 0;
    x = 0x80;
    for(i = 0; i < 8; i++)
    {
        HW_SET(clk);
        _DELAY();

        HW_CLR(clk);
        if(HW_GET(dio))
        {
            b |= x;
        }

        _DELAY();
        x >>= 1;
    }

    return b;
}

void SSPI_Clk(const HW_t *clk, uint8_t pluse)
{
    uint8_t i;

    for(i = 0; i < pluse; i++)
    {
        HW_SET(clk);
        _DELAY();

        HW_CLR(clk);
        _DELAY();
    }
}

void SSPI_Recv(const HW_t *clk, const HW_t *dio, void *data, unsigned int size)
{
    uint8_t *vdata;
    uint8_t i;

    vdata = (uint8_t *) data;
    for(i = 0; i < size; i++)
    {
        vdata[i] = SSPI_RecvByte(clk, dio);
    }
}

void SSPI_Idle(const SSPI_Bus_t *bus)
{
    HW_Set(bus->stb, HW_Level_High);
    HW_Set(bus->clk, HW_Level_Low);
//    HW_Set(bus->dio, HW_Level_High);
}
